import { _decorator, Component, Node, ScrollView, Label, UITransform, instantiate, Color, Prefab } from 'cc';
import { ColorsConst } from '../../../battle/Const';
import { LOG } from '../../../ConsoleLogCtrl';
const { ccclass, property } = _decorator;

/**
 * 消息数据接口
 */
export interface IMessageData {
    id: number;
    message: string;
    type: string;
    timestamp: Date;
}

/**
 * 日志统计面板类
 * 负责管理消息显示、滚动列表、消息样式等功能
 */
@ccclass('LogStatsPanel')
export class LogStatsPanel extends Component {
    @property(ScrollView)
    public messageScrollView: ScrollView = null;

    @property(Node)
    public messageContent: Node = null;

    @property(Prefab)
    public messageItemPrefab: Prefab = null;

    // 消息相关属性
    private messageList: IMessageData[] = [];
    private messageIdCounter: number = 0;
    private maxMessages: number = 100;
    private autoScrollToBottom: boolean = true;

    // 无限滚动相关属性
    private isInfiniteScrollEnabled: boolean = true;
    private itemHeight: number = 40;
    private visibleItemCount: number = 10;
    private bufferItemCount: number = 3; // 缓冲区额外渲染的消息数量
    private startIndex: number = 0;
    private endIndex: number = -1;
    private nodePool: Node[] = [];
    private visibleNodes: Map<number, Node> = new Map();
    private totalHeight: number = 0; // 总内容高度
    // 是否显示面板
    private _isVisible: boolean = false;

    onLoad() {
        this.initMessageScrollView();
    }

     /**
     * 初始化消息ScrollView
     */
    private initMessageScrollView() {
        if (!this.messageScrollView) {
            LOG.warn('MessageScrollView not assigned');
            return;
        }

        this.messageContent = this.messageScrollView.content;

        if (this.isInfiniteScrollEnabled) {
            // 设置ScrollView的滚动监听
            this.messageScrollView.node.on('scrolling', this.onScrolling, this);

            // 计算可见区域的消息数量
            const scrollViewHeight = this.messageScrollView.node.getComponent(UITransform).height;
            this.visibleItemCount = Math.ceil(scrollViewHeight / this.itemHeight) + this.bufferItemCount * 2;

            // 初始化内容区域
            this.updateContentSize();

            // 预创建节点池
            this.initNodePool();
        }
    }

    /**
     * 初始化节点池
     */
    private initNodePool() {
        this.nodePool = [];
        this.visibleNodes.clear();

        // 预创建一些节点
        const poolSize = this.visibleItemCount + 2; // 多创建2个用于缓冲
        for (let i = 0; i < poolSize; i++) {
            const node = this.createPoolNode();
            if (node) {
                node.active = false;
                this.nodePool.push(node);
            }
        }
    }

    /**
     * 创建池中的节点
     */
    private createPoolNode(): Node {
        const node = new Node('PooledMessageItem');
        node.setParent(this.messageContent);

        const transform = node.addComponent(UITransform);
        const width = this.messageContent.getComponent(UITransform).width
        transform.setContentSize(width, this.itemHeight);

        const label = node.addComponent(Label);
        label.fontSize = 14;
        label.lineHeight = 24;
        label.horizontalAlign = Label.HorizontalAlign.LEFT;
        label.verticalAlign = Label.VerticalAlign.CENTER;
        label.overflow = Label.Overflow.RESIZE_HEIGHT;
        label.isBold = false;

        return node;
    }

    /**
     * 滚动事件处理
     */
    private onScrolling() {
        if (!this.isInfiniteScrollEnabled) return;

        this.updateVisibleItems();
    }

    /**
     * 更新内容区域大小
     */
    private updateContentSize() {
        this.totalHeight = this.messageList.length * this.itemHeight;
        const contentTransform = this.messageContent.getComponent(UITransform);
        // 当消息列表为空时，设置一个最小高度，否则使用计算出的高度
        const minHeight = this.visibleItemCount * this.itemHeight;
        contentTransform.setContentSize(contentTransform.width, this.messageList.length > 0 ? Math.max(this.totalHeight, minHeight) : minHeight);
    }

    /**
     * 更新可见项目
     */
    private updateVisibleItems() {
        const scrollView = this.messageScrollView;
        const contentTransform = this.messageContent.getComponent(UITransform);
        const scrollViewTransform = scrollView.node.getComponent(UITransform);

        // 计算当前滚动位置
        const scrollOffset = scrollView.getScrollOffset();
        const viewTop = scrollOffset.y;
        const viewBottom = viewTop + scrollViewTransform.height;

        // 计算可见范围的索引
        const newStartIndex = Math.max(0, Math.floor(viewTop / this.itemHeight) - this.bufferItemCount);
        const newEndIndex = Math.min(this.messageList.length - 1,
            Math.ceil(viewBottom / this.itemHeight) + this.bufferItemCount);

        // 如果范围没有变化，直接返回
        if (newStartIndex === this.startIndex && newEndIndex === this.endIndex) {
            return;
        }

        // 回收不再可见的节点
        this.recycleInvisibleNodes(newStartIndex, newEndIndex);

        // 更新索引范围
        this.startIndex = newStartIndex;
        this.endIndex = newEndIndex;

        // 渲染新的可见项目
        this.renderVisibleItems();
    }

    /**
     * 回收不可见的节点
     */
    private recycleInvisibleNodes(newStartIndex: number, newEndIndex: number) {
        const toRecycle: number[] = [];

        this.visibleNodes.forEach((node, index) => {
            if (index < newStartIndex || index > newEndIndex) {
                node.active = false;
                this.nodePool.push(node);
                toRecycle.push(index);
            }
        });

        toRecycle.forEach(index => {
            this.visibleNodes.delete(index);
        });
    }

    /**
     * 渲染可见项目
     */
    private renderVisibleItems() {
        for (let i = this.startIndex; i <= this.endIndex; i++) {
            if (!this.visibleNodes.has(i) && i < this.messageList.length) {
                const node = this.getNodeFromPool();
                if (node) {
                    this.setupMessageNode(node, this.messageList[i], i);
                    this.visibleNodes.set(i, node);
                }
            }
        }
    }

    /**
     * 从池中获取节点
     */
    private getNodeFromPool(): Node | null {
        if (this.nodePool.length > 0) {
            return this.nodePool.pop();
        }

        // 如果池中没有节点，创建新的
        return this.createPoolNode();
    }

    /**
     * 设置消息节点内容
     */
    private setupMessageNode(node: Node, messageData: IMessageData, index: number) {
        node.active = true;

        // 设置位置 - 修复重叠问题
        // 在Cocos Creator中，ScrollView的content从顶部开始布局
        // 每个item应该从content的顶部向下排列，锚点在节点中心
        // 第一个节点应该在 -itemHeight/2 位置，第二个在 -itemHeight*1.5 位置，以此类推
        const yPos = -index * this.itemHeight - this.itemHeight / 2;
        node.setPosition(0, yPos, 0);

        // 设置内容
        const label = node.getComponent(Label);
        const timeStr = this.formatTime(messageData.timestamp);
        label.string = `[${timeStr}] ${messageData.message}`;

        // 设置样式
        this.setMessageNodeStyle(label, messageData.type);
    }

    /**
     * 显示消息
     * @param message 消息内容
     * @param type 消息类型（info, warning, error）
     */
    public showMessage(message: string, type: string = 'info') {
        this.addMessageToScrollView(message, type);
    }

    /**
     * 添加消息到ScrollView
     * @param message 消息内容
     * @param type 消息类型
     */
    private addMessageToScrollView(message: string, type: string) {
        if (!this.messageContent) {
            LOG.warn('MessageContent not initialized');
            return;
        }

        // 创建消息数据
        const messageData = {
            id: ++this.messageIdCounter,
            message: message,
            type: type,
            timestamp: new Date()
        };

        // 添加到消息列表
        this.messageList.push(messageData);

        if (this.isInfiniteScrollEnabled) {
            // 无限滚动模式
            this.updateContentSize();

            // 如果新消息在可见范围内，立即渲染
            const messageIndex = this.messageList.length - 1;
            if (messageIndex >= this.startIndex && messageIndex <= this.endIndex) {
                const node = this.getNodeFromPool();
                if (node) {
                    this.setupMessageNode(node, messageData, messageIndex);
                    this.visibleNodes.set(messageIndex, node);
                }
            }

            // 限制消息数量
            this.limitMessageCount();

            // 自动滚动到底部
            if (this.autoScrollToBottom) {
                this.scheduleOnce(() => {
                    this.scrollToBottom();
                }, 0.1);
            }
        } else {
            // 传统模式
            // 创建消息节点
            const messageNode = this.createMessageNode(messageData);
            messageNode.setParent(this.messageContent);

            // 限制消息数量
            this.limitMessageCount();

            // 自动滚动到底部
            if (this.autoScrollToBottom) {
                this.scheduleOnce(() => {
                    this.scrollToBottom();
                }, 0.1);
            }
        }
    }

    /**
     * 创建消息节点
     * @param messageData 消息数据
     * @returns 消息节点
     */
    private createMessageNode(messageData: IMessageData): Node {
        let messageNode: Node;

        if (this.messageItemPrefab) {
            // 使用预制体
            messageNode = instantiate(this.messageItemPrefab);
            // 设置消息内容
            const label = messageNode.getComponent(Label);
            const timeStr = this.formatTime(messageData.timestamp);
            label.string = `[${timeStr}] ${messageData.message}`;
        } else {
            // 创建默认消息节点
            messageNode = new Node(`Message_${messageData.id}`);

            const transform = messageNode.addComponent(UITransform);
            transform.setContentSize(360, this.itemHeight);

            const label = messageNode.addComponent(Label);
            label.fontSize = 14;
            label.lineHeight = 24;
            label.horizontalAlign = Label.HorizontalAlign.LEFT;
            label.verticalAlign = Label.VerticalAlign.CENTER;
            label.overflow = Label.Overflow.RESIZE_HEIGHT;
            label.isBold = false;

            // 设置消息内容
            const timeStr = this.formatTime(messageData.timestamp);
            label.string = `[${timeStr}] ${messageData.message}`;

            // 设置消息样式
            this.setMessageNodeStyle(label, messageData.type);
        }

        return messageNode;
    }

    /**
     * 限制消息数量
     */
    private limitMessageCount() {
        if (this.isInfiniteScrollEnabled) {
            // 无限滚动模式：只限制数据数组长度
            while (this.messageList.length > this.maxMessages) {
                this.messageList.shift();

                // 更新索引
                this.startIndex = Math.max(0, this.startIndex - 1);
                this.endIndex = Math.max(0, this.endIndex - 1);

                // 重新渲染可见项目
                this.clearVisibleNodes();
                this.updateContentSize();
                this.renderVisibleItems();
            }
        } else {
            // 传统模式：限制DOM节点数量
            while (this.messageContent.children.length > this.maxMessages) {
                const firstChild = this.messageContent.children[0];
                firstChild.destroy();
            }

            // 同时限制数据数组长度
            while (this.messageList.length > this.maxMessages) {
                this.messageList.shift();
            }
        }
    }

    /**
     * 清除所有可见节点
     */
    private clearVisibleNodes() {
        this.visibleNodes.forEach(node => {
            node.active = false;
            this.nodePool.push(node);
        });
        this.visibleNodes.clear();
    }

    /**
     * 滚动到底部
     */
    private scrollToBottom() {
        if (this.messageScrollView) {
            this.messageScrollView.scrollToBottom(0.3);
        }
    }

    /**
     * 格式化时间
     * @param date 日期对象
     * @returns 格式化的时间字符串
     */
    private formatTime(date: Date): string {
        const hours = date.getHours().toString();
        const minutes = date.getMinutes().toString();
        const seconds = date.getSeconds().toString();
        return `${hours}:${minutes}:${seconds}`;
    }

    /**
     * 设置消息节点样式
     * @param label 标签组件
     * @param type 消息类型
     */
    private setMessageNodeStyle(label: Label, type: string) {
        switch (type) {
            case 'info':
                label.color = Color.BLACK; // 黑色
                break;
            case 'warning':
                label.color = Color.YELLOW; // 黄色
                break;
            case 'error':
                label.color = Color.MAGENTA; // 紫色
                break;
            case 'success':
                label.color = Color.GREEN; // 绿色
                break;
            case 'debug':
                label.color = Color.BLUE; // 蓝色
                break;
            case 'player1':
                label.color = new Color(ColorsConst.logPlayer1Color); // 玩家1浅红色
                break;
            case 'player2':
                label.color = new Color(ColorsConst.logPlayer2Color); // 玩家2天蓝色
                break;
            case 'battle_result':
                label.color = new Color(ColorsConst.logResultColor); // 战斗结算金黄色
                break;
            default:
                label.color = Color.BLACK; // 默认黑色
                break;
        }
    }

    /**
     * 显示错误消息
     * @param message 错误消息
     */
    public showErrorMessage(message: string) {
        this.showMessage(message, 'error');
    }

    /**
     * 显示成功消息
     * @param message 成功消息
     */
    public showSuccessMessage(message: string) {
        this.showMessage(message, 'success');
    }

    /**
     * 显示警告消息
     * @param message 警告消息
     */
    public showWarningMessage(message: string) {
        this.showMessage(message, 'warning');
    }

    /**
     * 显示调试消息
     * @param message 调试消息
     */
    public showDebugMessage(message: string) {
        this.showMessage(message, 'debug');
    }

    /**
     * 清空所有消息并重置面板到初始状态
     */
    public clearAllMessages() {
        this.messageList = [];
        this.messageIdCounter = 0;

        if (this.isInfiniteScrollEnabled) {
            // 无限滚动模式：回收所有可见节点
            this.clearVisibleNodes();
            this.startIndex = 0;
            this.endIndex = -1;
            this.updateContentSize();
        } else {
            // 传统模式：销毁所有子节点
            if (this.messageContent) {
                this.messageContent.removeAllChildren();
            }
        }
    }

    /**
     * 设置最大消息数量
     * @param maxCount 最大消息数量
     */
    public setMaxMessageCount(maxCount: number) {
        this.maxMessages = maxCount;
        this.limitMessageCount();
    }

    /**
     * 设置是否自动滚动到底部
     * @param autoScroll 是否自动滚动
     */
    public setAutoScrollToBottom(autoScroll: boolean) {
        this.autoScrollToBottom = autoScroll;
    }

    /**
     * 手动滚动到底部
     */
    public scrollToBottomManually() {
        this.scrollToBottom();
    }

    /**
     * 获取消息数量
     * @returns 当前消息数量
     */
    public getMessageCount(): number {
        return this.messageList.length;
    }

    /**
     * 启用无限滚动
     */
    public enableInfiniteScroll(enable: boolean = true) {
        if (this.isInfiniteScrollEnabled === enable) {
            return;
        }

        this.isInfiniteScrollEnabled = enable;

        if (enable) {
            // 启用无限滚动
            this.initMessageScrollView();

            // 清除现有的DOM节点，转换为无限滚动模式
            this.messageContent.removeAllChildren();
            this.renderVisibleItems();
        } else {
            // 禁用无限滚动
            this.clearVisibleNodes();

            // 移除滚动监听
            if (this.messageScrollView) {
                this.messageScrollView.node.off('scrolling', this.onScrolling, this);
            }

            // 重新创建所有消息节点
            this.recreateAllMessages();
        }
    }

    /**
     * 重新创建所有消息节点（用于从无限滚动切换到传统模式）
     */
    private recreateAllMessages() {
        this.messageList.forEach(messageData => {
            const messageNode = this.createMessageNode(messageData);
            messageNode.setParent(this.messageContent);
        });
    }

    /**
     * 设置项目高度（仅在无限滚动模式下有效）
     */
    public setItemHeight(height: number) {
        this.itemHeight = height;
        if (this.isInfiniteScrollEnabled) {
            this.updateContentSize();
            this.updateVisibleItems();
        }
    }

    /**
     * 获取当前是否启用无限滚动
     */
    public isInfiniteScrollMode(): boolean {
        return this.isInfiniteScrollEnabled;
    }

    /**
     * 获取可见节点数量（调试用）
     */
    public getVisibleNodeCount(): number {
        return this.visibleNodes.size;
    }

    /**
     * 获取节点池大小（调试用）
     */
    public getPoolSize(): number {
        return this.nodePool.length;
    }

     /**
     * 显示面板
     */
     public showPanel() {
        this.node.active = true;
        this._isVisible = true;
        if(this._isVisible){
            this.updateVisibleItems()
        }

    }

    /**
     * 隐藏面板
     */
    public hidePanel() {
        this.node.active = false;
        this._isVisible = false;

    }
}